﻿using Engine;
using Game;

namespace MFTrain
{
    public class SubsystemMFRailBlockBehavior : SubsystemBlockBehavior
    {
        protected Point3[,] m_pointsToUpdate = new Point3[4, 3]
        {
            {
                new Point3(0, 0, -1),
                new Point3(0, 1, -1),
                new Point3(0, -1, -1)
            },
            {
                new Point3(-1, 0, 0),
                new Point3(-1, 1, 0),
                new Point3(-1, -1, 0)
            },
            {
                new Point3(0, 0, 1),
                new Point3(0, 1, 1),
                new Point3(0, -1, 1)
            },
            {
                new Point3(1, 0, 0),
                new Point3(1, 1, 0),
                new Point3(1, -1, 0)
            }
        };

        public override int[] HandledBlocks => new int[1] { 543 };

        public override void OnBlockAdded(int value, int oldValue, int x, int y, int z)
        {
            UpdateCornerState(x, y, z, 1, MFRailBlock.IsBreaker(Terrain.ExtractData(value)));
        }

        public override void OnNeighborBlockChanged(int x, int y, int z, int neighborX, int neighborY, int neighborZ)
        {
            int cellValue = base.SubsystemTerrain.Terrain.GetCellValue(x, y - 1, z);
            if (BlocksManager.Blocks[Terrain.ExtractContents(cellValue)].IsTransparent_(cellValue))
            {
                base.SubsystemTerrain.DestroyCell(0, x, y, z, 0, noDrop: false, noParticleSystem: false);
            }
            else
            {
                UpdateCornerState(x, y, z, 1, MFRailBlock.IsBreaker(Terrain.ExtractData(base.SubsystemTerrain.Terrain.GetCellValue(x, y, z))));
            }
        }

        private void UpdateCornerState(int x, int y, int z, int step, bool isBreaker)
        {
            int? num = null;
            bool[] array = new bool[4];
            bool[] array2 = new bool[4];
            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Point3 point = m_pointsToUpdate[i, j];
                    int cellValueFastChunkExists = base.SubsystemTerrain.Terrain.GetCellValueFastChunkExists(x + point.X, y + point.Y, z + point.Z);
                    if (Terrain.ExtractContents(cellValueFastChunkExists) == 543)
                    {
                        if (j == 1)
                        {
                            array2[i] = MFRailBlock.CanConnectTo(MFRailBlock.GetRailType(Terrain.ExtractData(cellValueFastChunkExists)), i);
                        }
                        else
                        {
                            array[i] = MFRailBlock.CanConnectTo(MFRailBlock.GetRailType(Terrain.ExtractData(cellValueFastChunkExists)), i);
                        }

                        if (step > 0)
                        {
                            UpdateCornerState(x + point.X, y + point.Y, z + point.Z, step - 1, MFRailBlock.IsBreaker(Terrain.ExtractData(cellValueFastChunkExists)));
                        }

                        break;
                    }
                }
            }

            if (array[0] && array[3])
            {
                num = 1;
            }
            else if (array[0] && array[1])
            {
                num = 2;
            }
            else if (array[1] && array[2])
            {
                num = 3;
            }
            else if (array[2] && array[3])
            {
                num = 0;
            }
            else if (array2[2])
            {
                num = 6;
            }
            else if (array2[0])
            {
                num = 8;
            }
            else if (array2[3])
            {
                num = 7;
            }
            else if (array2[1])
            {
                num = 9;
            }
            else if (array[0] || array[2])
            {
                num = 4;
            }
            else if (array[1] || array[3])
            {
                num = 5;
            }

            if (num.HasValue)
            {
                base.SubsystemTerrain.ChangeCell(x, y, z, Terrain.MakeBlockValue(543, 0, MFRailBlock.SetRailType(isBreaker ? MFRailBlock.SetBreaker(0) : 0, num.Value)));
            }
        }
    }
}